package cn.restcloud.example.controller.rdb;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.bson.Document;

import cn.restcloud.example.dao.IDemoUserDao;
import cn.restcloud.example.model.UserModel;
import cn.restcloud.framework.core.annotation.bean.BeanConfig;
import cn.restcloud.framework.core.annotation.bean.BeanType;
import cn.restcloud.framework.core.annotation.bean.IocBeanId;
import cn.restcloud.framework.core.annotation.rest.MethodType;
import cn.restcloud.framework.core.annotation.rest.Param;
import cn.restcloud.framework.core.annotation.rest.Params;
import cn.restcloud.framework.core.annotation.rest.RestConfig;
import cn.restcloud.framework.core.base.IBasePageBean;
import cn.restcloud.framework.core.container.BeanFactory;
import cn.restcloud.framework.core.util.RequestUtil;
import cn.restcloud.framework.core.util.db.rdb.RdbMapperUtil;
import cn.restcloud.framework.core.util.db.rdb.RdbUtil;
import cn.restcloud.framework.view.base.DocAndView;
import cn.restcloud.framework.view.util.ViewUtil;

/**
 * 关系数据库分页示例Demo
 * @author Administrator
 *
 */
@BeanConfig(appId = "example",beanId = "ListByPageDemoRest",beanName = "关系数据库分页查询示例",beanType = BeanType.CONTROLLER,autowired = true,singleton = true,hotMode = true)
@RestConfig(url = "/rest/example/rdb/pages")
public class ListByPageDemoRest {
	@IocBeanId(beanId = "DemoUserRdb") //指定注入关系数据库的实现类
	private IDemoUserDao dao;
	
	/**
	 * Dao实现类中使用RdbPageUtil进行分页查询，只能通过filters,searchFilters传入查询条件有一定的灵活性限制
	 * 不能自定义写sql条件来选择数据，适合于查询全部数据并进行分页
	 * @return
	 */
	@RestConfig(configName = "分页查询用户数据",method = MethodType.GET,url = "/list1")
	@Params({
		@Param(id = "PageNo", name = "当前页兼容page"),
		@Param(id = "pageSize", name = "每页显示数兼容rows"),
		@Param(id = "sort", name = "动态排序字段"),
		@Param(id = "order", name = "排序方向ASC|DESC"),
		@Param(id = "filters", name = "动态过滤条件",sampleValue="{\"fieldName\":\"value\"}"),
		@Param(id = "searchFilters", name = "动态搜索条件",sampleValue="{\"title\":\"test\",\"content\":\"test\"}")
	})
	public DocAndView listByPage_1() throws Exception{
		IBasePageBean<UserModel> pageBean=dao.listByPage();
		return ViewUtil.getJsonView(pageBean);
	}
	
	
	/**
	 * Dao实现类中使用继承的RdbBaseDao中的listByPage（）方法进行分页查询，可以自定义查询sql条件
	 * 不能动态传入filters,searchFilters条件进去，因为在Dao实现类中已经把sql条件固定死了
	 * 条件可以自已接收state参数然后传入
	 * @return
	 */
	@RestConfig(configName = "分页查询state=1的用户数据",method = MethodType.GET,url = "/list2")
	@Params({
		@Param(id = "PageNo", name = "当前页兼容page"),
		@Param(id = "pageSize", name = "每页显示数兼容rows"),
		@Param(id = "sort", name = "动态排序字段"),
		@Param(id = "order", name = "排序方向ASC|DESC")
	})
	public DocAndView listByPage_2() throws Exception{
		IBasePageBean<UserModel> pageBean=dao.listByPageAndState("1");
		return ViewUtil.getJsonView(pageBean);
	}
	
	/**
	 * Dao实现类中使用继承的RdbBaseDao中的listByPage（）方法进行分页查询，可以自定义查询sql条件
	 * 可以动态传入filters,searchFilters条件进去，因为在Dao实现类中可以合并sql where条件和filters条件
	 * @return
	 */
	@RestConfig(configName = "分页查询state=1的用户数据",method = MethodType.GET,url = "/list3")
	@Params({
		@Param(id = "PageNo", name = "当前页兼容page"),
		@Param(id = "pageSize", name = "每页显示数兼容rows"),
		@Param(id = "sort", name = "动态排序字段"),
		@Param(id = "order", name = "排序方向ASC|DESC"),
		@Param(id = "filters", name = "动态过滤条件",sampleValue="{\"fieldName\":\"value\"}"),
		@Param(id = "searchFilters", name = "动态搜索条件",sampleValue="{\"title\":\"test\",\"content\":\"test\"}")
	})
	public DocAndView listByPage_3() throws Exception{
		IBasePageBean<UserModel> pageBean=dao.listByPageAndState("1");
		return ViewUtil.getJsonView(pageBean);
	}
	
	/**
	 * Dao实现类中使用RdbUtil.listBeansByPage()方法进行分页查询
	 * @return
	 */
	@RestConfig(configName = "分页查询state=1的用户数据",method = MethodType.GET,url = "/list4")
	@Params({
		@Param(id = "PageNo", name = "当前页"),
		@Param(id = "pageSize", name = "每页显示数")
	})
	public DocAndView listByPage_4() throws Exception{
		IBasePageBean<UserModel> pageBean=dao.listByPageBySqlWhere("1");
		return ViewUtil.getJsonView(pageBean);
	}
	
	/**
	 * 直接组合一个自定义的sql语句去数据库中查询数据并分页
	 * 需要自已根据不同的数据库类型mssql,mysql,oracle组合不同的sql查询语句
	 * 本方法虽然灵活快速（因为没有编写dao接口和实现类）但在架构分层上不太好，如果是为了快速实现功能可以用用，如果是构建一个好的产品最好是把数据的访问和sql的执行放到dao实现类中去
	 * @return
	 */
	@RestConfig(configName = "分页查询用户state=1的用户数据",method = MethodType.GET,url = "/list5")
	@Params({
		@Param(id = "PageNo", name = "当前页")
	})
	public DocAndView listByPage_5() throws Exception{
		//先生成一个pageBean对像用来返回查询后的数据
		IBasePageBean<UserModel> pageBean=BeanFactory.getBean(IBasePageBean.class);
		String state="1"; //这里也可以使用RequestUtil.getString("state")来传入参数
		
		//先计算文档总数，分页时必须要有总数才能算出有多少页
		String sql="select count(*) as totalNum from P_OrgPersons where state=?";
		String totalRecords=RdbUtil.getColumnValue(sql, state);
		
		//再根据当前页进行分页查询，这里的sql以ms sql为示例
		String urlPageNo=RequestUtil.getString("pageNo");
		if(StringUtils.isBlank(urlPageNo)){urlPageNo="1";}
    	int pageNo=Integer.parseInt(urlPageNo);
    	int pageSize=20;
        int endRow = pageNo * pageSize;
        int beginRow = (pageNo - 1) * pageSize+1; //如果是sql server需要加1
		sql="select * from (select *,row_number() over(order by editTime) as RowNumber from P_OrgPersons as t where state=?) a where RowNumber between ? and ?";
		List<UserModel> userModels=RdbUtil.listBeans(UserModel.class, sql, state,beginRow,endRow);
		
		pageBean.setTotal(Integer.parseInt(totalRecords)); //设置总数
    	pageBean.setPageBeans(userModels);//返回数据到pageBean中去
    	
		return ViewUtil.getJsonView(pageBean);
	}
	
	/**
	 * 使用Sql配置中的sql进行分页查询,相对于listByPage_5()方法的优势是sql语句是统一配置的，没有写死在java代码中
	 * Sql配置中必须配置为动态sql且必须定义sql和countSql两个变量，sql用来返回分页查询的sql语句,countSql要用来返回计算总算的sql语句
	 * @return
	 */
	@RestConfig(configName = "分页查询用户state=1的用户数据",method = MethodType.GET,url = "/list6")
	@Params({
		@Param(id = "PageNo", name = "当前页")
	})
	public DocAndView listByPage_6() throws Exception{
		//先生成一个pageBean对像用来返回查询后的数据
		String urlPageNo=RequestUtil.getString("pageNo");
		if(StringUtils.isBlank(urlPageNo)){urlPageNo="1";}
    	int pageNo=Integer.parseInt(urlPageNo);
    	int pageSize=20;
		String configId="example.selectpagesql";
		Document paramDoc=new Document(); //用来传入到sql中的变量
		paramDoc.put("state", 1);
		IBasePageBean<Document> pageBean=RdbMapperUtil.selectListByPage(configId, pageNo, pageSize, paramDoc);
		return ViewUtil.getJsonView(pageBean);
	}
	
}
